﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ChatForum.Domain;
using ChatForum.REST.ServiceContract;
using System.ServiceModel.Web;
using ChatForum.DataContract;

namespace ChatForum.Service.REST
{
    public class ForumService : ServiceBase, IForumService
    {
        public ForumService(BusinessLogic logic)
            : base(logic)
        { }

        #region /categories
        public void CreateCategory(CategoryDTO category)
        {
            try
            {
                if (category == null)
                {
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
                    return;
                }
                logic.CreateCategory(category.Convert());
                Uri locationUri = new Uri(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri.OriginalString + "/" + category.Name);
                WebOperationContext.Current.OutgoingResponse.SetStatusAsCreated(locationUri);
            }
            catch (Exception ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public void DeleteAllCategory()
        {
            try
            {
                throw new NotImplementedException();
            }
            catch (NotImplementedException ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.NotImplemented);
            }
        }
        public void DeleteCategory(string categoryTitle)
        {
            try
            {
                throw new NotImplementedException();
            }
            catch (NotImplementedException ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.NotImplemented);
            }
        }
        public IEnumerable<CategoryDTO> GetAllCategory()
        {
            try
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;
                return logic.GetAllCategory().Select(u => new CategoryDTO(u));
            }
            catch (Exception ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public CategoryDTO GetCategory(string categoryTitle)
        {
            try
            {
                Category category = logic.GetAllCategory().FirstOrDefault(c => c.Name.Equals(categoryTitle, StringComparison.OrdinalIgnoreCase));
                if (category == null)
                {
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
                    return null;
                }
                else
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;
                return new CategoryDTO(category);
            }
            catch (Exception ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public void ModifyAllCategory(IEnumerable<CategoryDTO> categoryCollection)
        {
            try
            {
                if (categoryCollection == null || categoryCollection.Count() == 0)
                {
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
                    return;
                }
                foreach (CategoryDTO user in categoryCollection)
                {
                    logic.ModifyCategory(user.Convert());
                }
            }
            catch (NotImplementedException ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public void ModifyCategory(string categoryTitle, CategoryDTO category)
        {
            try
            {
                if (category == null)
                {
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
                    return;
                }
                logic.ModifyCategory(category.Convert());
            }
            catch (NotImplementedException ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        #endregion

        #region /categories/{categorytitle}/posts
        public void CreatePost_Category(string categoryTitle, PostDTO post)
        {
            try
            {
                if (post != null)
                {
                    Category cat = logic.GetAllCategory().FirstOrDefault(c => c.Name == categoryTitle);
                    if (cat != null)
                    {
                        Post p = post.Convert();
                        p.ParentCategory = cat.ID;
                        logic.CreatePost(p);
                        Uri locationUri = new Uri(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri.OriginalString + "?postId=" + post.ID);
                        WebOperationContext.Current.OutgoingResponse.SetStatusAsCreated(locationUri);
                    }
                }
                else
                {
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
                    return;
                }
            }
            catch (Exception ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public void DeleteAllPost_Category(string categoryTitle)
        {
            throw new NotImplementedException();
        }
        public void DeletePost_Category(string categoryTitle, Guid postId)
        {
            throw new NotImplementedException();
        }
        public IEnumerable<PostDTO> GetAllPost_Category(string categoryTitle)
        {
            try
            {
                Category cat = logic.GetAllCategory().FirstOrDefault(c => c.Name == categoryTitle);
                if (cat == null)
                {
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
                    return null;
                }
                return logic.GetPostbyCategory(cat.ID, true).Select(p => new PostDTO(p));
            }
            catch (Exception ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public PostDTO GetPost_Category(string categoryTitle, Guid postId)
        {
            try
            {
                Category cat = logic.GetAllCategory().FirstOrDefault(c => c.Name == categoryTitle);
                if (cat != null)
                {
                    Post post = logic.GetPostbyCategory(cat.ID, true).FirstOrDefault(p => p.ID == postId);
                    if (post != null)
                        return new PostDTO(post);
                }
                WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
                return null;
            }
            catch (Exception ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public void ModifyAllPost_Category(string categoryTitle, IEnumerable<PostDTO> postCollection)
        {
            throw new NotImplementedException();
        }
        public void ModifyPost_Category(string categoryTitle, Guid postId, PostDTO post)
        {
            throw new NotImplementedException();
        }
        #endregion

        #region /categories/{categorytitle}/thread
        public void CreateThread_Category(string categoryTitle, PostDTO post)
        {
            try
            {
                if (post != null)
                {
                    Category cat = logic.GetAllCategory().FirstOrDefault(c => c.Name == categoryTitle);
                    if (cat != null)
                    {
                        Post p = post.Convert();
                        p.ParentCategory = cat.ID;
                        p.ParentPost = Guid.Empty;
                        logic.CreatePost(p);
                        Uri locationUri = new Uri(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri.OriginalString + "?postId=" + post.ID);
                        WebOperationContext.Current.OutgoingResponse.SetStatusAsCreated(locationUri);
                    }
                }
                else
                {
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
                    return;
                }
            }
            catch (Exception ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public void PostThread_Category(string categoryTitle, Guid postId, PostDTO post)
        {
            try
            {
                if (post != null)
                {
                    Category cat = logic.GetAllCategory().FirstOrDefault(c => c.Name == categoryTitle);
                    if (cat != null)
                    {
                        Post parentPost = logic.GetPostbyCategory(cat.ID, true).FirstOrDefault(p => p.ID == postId);
                        if (parentPost != null)
                        {
                            Post p = post.Convert();
                            p.ParentCategory = cat.ID;
                            p.ParentPost = parentPost.ID;
                            logic.CreatePost(p);
                            WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Created;
                        }
                    }
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
                    return;
                }
                else
                {
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
                    return;
                }
            }
            catch (Exception ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public void DeleteAllThread_Category(string categoryTitle)
        {
            throw new NotImplementedException();
        }
        public void DeleteThread_Category(string categoryTitle, Guid postId)
        {
            throw new NotImplementedException();
        }
        public IEnumerable<ThreadDTO> GetAllThread_Category(string categoryTitle)
        {
            try
            {
                Category cat = logic.GetAllCategory().FirstOrDefault(c => c.Name == categoryTitle);
                if (cat == null)
                {
                    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
                    return null;
                }
                return logic.GetPostbyCategory(cat.ID, false).Select(p => new ThreadDTO(p));
            }
            catch (Exception ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public IEnumerable<PostDTO> GetThread_Category(string categoryTitle, Guid postId)
        {
            try
            {
                Category cat = logic.GetAllCategory().FirstOrDefault(c => c.Name == categoryTitle);
                if (cat != null)
                {
                    Post post = logic.GetPostbyCategory(cat.ID, true).FirstOrDefault(p => p.ID == postId);
                    if (post != null)
                        return logic.GetThread(post.ID).Select(p => new PostDTO(p));
                }
                WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
                return null;
            }
            catch (Exception ex)
            {
                throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
            }
        }
        public void ModifyAllThread_Category(string categoryTitle, IEnumerable<PostDTO> threadCollection)
        {
            throw new NotImplementedException();
        }
        public void ModifyThread_Category(string categoryTitle, Guid postId, IEnumerable<PostDTO> thread)
        {
            throw new NotImplementedException();
        }
        #endregion


    }
}
